package org.javaboy.lock;

import redis.clients.jedis.params.SetParams;

import java.util.Arrays;
import java.util.Random;
import java.util.UUID;

public class LockDemo {
    public static void main(String[] args) {
        new RedisClient().execute(jedis -> {
            // 获取锁，如果获取到锁，则返回 1，否则返回 0
//            long lock = jedis.setnx("lock", "1");
            // 最好能够为锁设置一个过期时间，防止死锁，时间到了，自动释放锁
            String value = UUID.randomUUID().toString();
            // setnx+setex 组合，原子性
            String set = jedis.set("lock", value, SetParams.setParams().nx().ex(100));
            if ("OK".equals(set)) {
                // 获取到锁，执行业务逻辑
                // 执行自己的业务层代码
                System.out.println("执行业务层代码");
                //判断锁是否是自己加的锁，如果是，则可以释放锁
                // eval('脚本标记',List keys,Object...args)
                // lua 脚本
//                if (jedis.get("lock").equals(value)) {
//                     释放锁
//                    jedis.del("lock");
//                }
                jedis.evalsha("a5680effa13728b76dcee7c24a3d5f04bca1dde3", Arrays.asList("lock"), Arrays.asList(value));
            } else {
                // 没有获取到锁，重试
                try {
                    Thread.sleep(500);
                    // 递归调用（但是会有次数限制）
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }
}
